import SpawnController, { getCreeps } from '@/modules/structures/spawn'
import {
    AnyTransportTask,
    MoreToOneTransportData,
    OneToMoreTransportData,
    OneToOneTransportData,
    TransportMemory,
} from './types'
import { CreepRoles, SpawnTask } from '@/modules/structures/spawn/types'
import { BodyPartArrayType } from '@/utils/common'
import { generateId, isRoomInterval } from '@/ayaka'
import { createTransporterBody, deleteTransportTask, transporterWork } from './transporter'

/**
 * （房内）运输任务
 */
export default class TransportTaskManager {
    /**
     * 不可实例化
     */
    protected constructor() {
        throw new Error('BuildTask 不可被实例化！')
    }

    /**
     * 获取 memory
     */
    public static getMemory(room: Room) {
        if (!room.memory.transport) {
            room.memory.transport = {
                transporter: [],
                tasks: [],
            }
        }

        return room.memory.transport
    }

    /**
     * 执行运输任务
     */
    public static run(room: MyRoom) {
        const memory = TransportTaskManager.getMemory(room)

        const transporters = TransportTaskManager.getTransporter(room, memory.transporter)
        TransportTaskManager.spawnTransporter(room, transporters, memory)
        transporterWork(room, transporters, memory)
    }

    /**
     * 孵化搬运工
     */
    protected static spawnTransporter(room: MyRoom, creeps: Creep[], memory: TransportMemory) {
        if (!isRoomInterval(room, 31)) return

        creeps = creeps.filter((creep) => {
            return !creep.ticksToLive || creep.ticksToLive > creep.body.length * 3 + 50
        })

        const number = room.controller.level >= 5 ? 2 : 3
        if (creeps.length >= number) return

        if (SpawnController.searchSpawnTaskByRole(room, CreepRoles.transporter).length) return

        if (
            !room.storage &&
            !room.terminal &&
            (!room.container.length || room.container.every((c) => c.store['energy'] < 400))
        ) {
            return
        }

        TransportTaskManager.addTransporterSpawnTask(room, memory.transporter, createTransporterBody(room))
    }

    /**
     * 获取搬运工
     */
    protected static getTransporter(room: MyRoom, creepNames: string[]) {
        return getCreeps(room, creepNames)
    }

    /**
     * 添加 transporter 孵化任务
     */
    protected static addTransporterSpawnTask(room: Room, creepNames: string[], body: BodyPartArrayType) {
        const task: SpawnTask = {
            role: CreepRoles.transporter,
            body,
            defaultAdaption: true,
        }
        const creepName = SpawnController.addSpawnTask(room, task)
        if (!creepName) return

        creepNames.push(creepName)
    }

    /**
     * 添加运输任务
     */
    public static addTransportTask(room: MyRoom, task: AnyTransportTask) {
        const memory = TransportTaskManager.getMemory(room)

        const index = memory.tasks.findIndex((t) => t.priority > task.priority)
        if (~index) {
            memory.tasks.splice(index, 0, task)
        } else {
            memory.tasks.push(task)
        }
    }

    /**
     * 发布一对一运输任务
     */
    public static addOneToOneTransportTask(
        room: MyRoom,
        name: string,
        data: OneToOneTransportData,
        priority = 6,
        subName?: string,
        pauseWhenEnemy?: boolean,
    ) {
        TransportTaskManager.addTransportTask(room, {
            id: generateId(),
            type: 'oneToOne',
            priority,
            data,
            name,
            subName,
            pauseWhenEnemy,
        })
    }

    /**
     * 发布一对多运输任务
     */
    public static addOneToMoreTransportTask(
        room: MyRoom,
        name: string,
        data: OneToMoreTransportData,
        priority = 4,
        subName?: string,
    ) {
        TransportTaskManager.addTransportTask(room, {
            id: generateId(),
            type: 'oneToMore',
            priority,
            data,
            name,
            subName,
        })
    }

    /**
     * 发布多对一运输任务
     */
    public static addMoreToOneTransportTask(
        room: MyRoom,
        name: string,
        data: MoreToOneTransportData,
        priority = 4,
        subName?: string,
    ) {
        TransportTaskManager.addTransportTask(room, {
            id: generateId(),
            type: 'moreToOne',
            priority,
            data,
            name,
            subName,
        })
    }

    /**
     * 移除运输任务
     */
    public static removeTransportTask(room: MyRoom, taskId: string) {
        const memory = TransportTaskManager.getMemory(room)
        deleteTransportTask(memory.tasks, taskId)
    }

    /**
     * 搜索指定名称的运输任务
     */
    public static searchTransportTaskByName(room: MyRoom, name: string) {
        const memory = TransportTaskManager.getMemory(room)

        return memory.tasks.filter((task) => task.name === name)
    }

    /**
     * 搜索指定子名称的任务
     */
    public static searchTransportTaskBySubName(room: MyRoom, subName: string) {
        const memory = TransportTaskManager.getMemory(room)

        return memory.tasks.filter((task) => task.subName === subName)
    }
}
